package com.jy.project.service.imp;

import cn.hutool.core.util.IdUtil;
import com.alibaba.fastjson.JSONObject;
import com.jy.project.constant.MaterialConstant;
import com.jy.project.controller.ApplyController;
import com.jy.project.controller.MatericalController;
import com.jy.project.domain.*;
import com.jy.project.dto.*;
import com.jy.project.enums.ApplyTypeEnum;
import com.jy.project.enums.ApplyTypeMatericalEnum;
import com.jy.project.enums.QualityStatusEnum;
import com.jy.project.ex.BizException;
import com.jy.project.mapper.*;
import com.jy.project.service.ApplyService;
import com.jy.project.service.imp.defult.DefaultApplyBusinessImp;
import com.jy.project.util.*;
import com.jy.project.vo.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.stereotype.Service;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.util.CollectionUtils;
import tk.mybatis.mapper.entity.Example;

import java.util.*;


//退库
@Service("applyStockReturnServiceImpl")
@Slf4j
public class ApplyStockReturnServiceImpl extends DefaultApplyBusinessImp implements ApplyService {

    @Autowired
    private ApplyMapper applyMapper;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private MaterialMapper materialMapper;

    @Autowired
    private ApplyCollectMapper applyCollectMapper;


    @Autowired
    private ApplyStockReturnMapper applyStockReturnMapper;


    @Autowired
    private RedisUtils redisUtils;

    @Autowired
    DataSourceTransactionManager dataSourceTransactionManager;

    @Autowired
    TransactionDefinition transactionDefinition;


    @Override
    public boolean insertApply(ApplyDTO dto) {
        dto.setApplyType(ApplyTypeEnum.STOCK_RETURN.getCode());
        Set<Integer> set = new HashSet<>();
        set.add(dto.getApplyType());
        dto.setExt(JSONObject.toJSONString(set));
        TransactionStatus transactionStatus = dataSourceTransactionManager.getTransaction(transactionDefinition);
        try {
            boolean bl = this.insertApplyBusiness(dto);
            if (bl == false) {
                throw new BizException("申请借用失败");
            }
        } catch (Exception e) {
            dataSourceTransactionManager.rollback(transactionStatus);
            throw e;
        }
        dataSourceTransactionManager.commit(transactionStatus);
        return true;
    }

    @Override
    public List<ApplyQualitVO> listApplyQualityVO(ApplyQueryDTO dto) {

        return applyMapper.listApplyyQualityVO(dto);
    }

    @Override
    public List<ApplyDeptAdminVO> listDeptAdminApplyVO(ApplyDeptAdminQueryDTO dto) {
        return null;
    }

    @Override
    public boolean applyAdopt(ApplyAdoptDTO dto) {
        log.info("审批通过退库单");
        String applyNo = dto.getApplyNo();
        Apply apply = applyMapper.getApplyByApplyNo(applyNo);
        if (apply==null){
            throw  new BizException("申请单不存在");
        }
        Example example =new Example(ApplyCollect.class);
        example.createCriteria().andEqualTo("applyNo",applyNo);
        ApplyStockReturn applyStockReturn = applyStockReturnMapper.selectOneByExample(example);
        if(applyStockReturn==null){
            throw  new BizException("退库数据不存在");
        }
        List<String> materialNos=new ArrayList<>();
        String materialNo = applyStockReturn.getMaterialNo();
        materialNos.add(materialNo);
        String reginNo = applyStockReturn.getReginNo();
        String reginName = applyStockReturn.getReginName();
        String storageLocation = applyStockReturn.getStorageLocation();
        ApplyUpdateReturnStockDTO applyUpdateCollectDTO=new ApplyUpdateReturnStockDTO();
        String s = CommonStringUtils.toStr(materialNos);
        applyUpdateCollectDTO.setMaterialNos(s);
        applyUpdateCollectDTO.setUseStatus(0);
        applyUpdateCollectDTO.setUseCompanyNo("");
        applyUpdateCollectDTO.setUseCompanyName("");
        applyUpdateCollectDTO.setUseDeptNo("");
        applyUpdateCollectDTO.setUseDeptName("");
        applyUpdateCollectDTO.setUseUserId(0L);
        applyUpdateCollectDTO.setUseNickName("");
        applyUpdateCollectDTO.setReginNo(reginNo);
        applyUpdateCollectDTO.setReginName(reginName);
        applyUpdateCollectDTO.setStorageLocation(storageLocation);
        materialMapper.updateRuturnStockApplyUpdateCollectDTO(applyUpdateCollectDTO);
        return true;
    }

    @Override
    public boolean applyReject(ApplyAdoptDTO dto) {
        log.info("驳回通过退库单");

        return true;
    }

    @Override
    public ServiceResultUtils listMaterialDetailsVO(MaterialDetailsDTO dto) {
        return null;
    }

    @Override
    public List<ApplyUserVO> listUserApplyVO(ApplyUserQueryDTO dto) {
        return null;
    }

    @Override
    public void checkApplyNo(String applyNo) {


    }



    @Override
    public MaterialVO checkMaterialNo(String materialNo) {
        return super.checkMaterialNo(materialNo);
    }

    @Override
    public synchronized  boolean  insertApplyBusiness(ApplyDTO dto) {
        if (dto == null) {
            throw new BizException("Apply对象为空");
        }
        //制单人
        Long id =dto.getUserId();
        User user = userMapper.selectByPrimaryKey(id);
        if (user == null) {
            throw new BizException("用户信息可能找不到");
        }
        ApplyStockReturnDTO applyStockReturnDTO = (ApplyStockReturnDTO) dto;
        StockReturnMaterialDTO[] stockReturnMaterialDTOS = applyStockReturnDTO.getStockReturnMaterialDTOS();
        String[] split=new String[stockReturnMaterialDTOS.length];
        for (int i = 0; i < stockReturnMaterialDTOS.length; i++) {
            split[i]=stockReturnMaterialDTOS[i].getMaterialNo();
        }
        if (split.length==0){
            throw new BizException("请选择退库的资产");
        }
        String remarks = dto.getRemarks();
        List<MaterialVO> materialVOS = checkMaterialNos(split);

        for (int i = 0; i < materialVOS.size(); i++) {
            Apply ay = create();
            ay.setApplyNo(CodeUtils.generateApplyNo(ApplyTypeMatericalEnum.STOCK_RETURN.getValue()));
            Date date = new Date();
            MaterialVO materialVO = materialVOS.get(i);
            String materialNo = materialVO.getMaterialNo();
            String name = materialVO.getName();
            ay.setMaterialNo(materialNo);
            ay.setMaterialName(name);
            ay.setCreateAt(date);
            ay.setUpdateAt(date);
            ay.setUpdateDay(date);
            ay.setIsDelete(0);
            ay.setApplyType(ApplyTypeEnum.STOCK_RETURN.getCode());
            ay.setName(ApplyTypeEnum.getValue(ay.getApplyType()));
            ay.setId(null);
            ay.setApplicantCompanyNo(user.getCompanyNo());
            ay.setApplicantCompanyName(user.getCompanyName());
            ay.setApplicantDeptNo(user.getDeptNo());
            ay.setApplicantDeptName(user.getDeptName());
            ay.setApplicantUserId(user.getId());
            ay.setApplicantUserNickName(user.getNickName());
            ay.setExt(dto.getExt());
            ay.setRemarks(dto.getRemarks());
            String companyName = materialVO.getCompanyName();
            String companyNo = materialVO.getCompanyNo();
            String useDeptName = materialVO.getUseDeptName();
            String useDeptNo = materialVO.getUseDeptNo();
            String useNickName = materialVO.getUseNickName();
            ay.setUseCompanyName(companyName);
            ay.setUseCompanyNo(companyNo);
            ay.setUseDeptName(useDeptName);
            ay.setUseDeptNo(useDeptNo);
            ay.setStatus(0);
            ay.setUseNickName(useNickName);
            ay.setRemarks(remarks);
            Long useUserId = materialVO.getUseUserId();
            ay.setUseUserId(useUserId);
            ApplyStockReturn applyStockReturn =new ApplyStockReturn();
            BeanUtils.copyProperties(applyStockReturnDTO,applyStockReturn);
            String managementCompanyNo = materialVO.getManagementCompanyNo();
            String managementCompanyName = materialVO.getManagementCompanyName();
            String managementDeptNo = materialVO.getManagementDeptNo();
            String managementDeptName = materialVO.getManagementDeptName();
            Long managementUserId = materialVO.getManagementUserId();
            ay.setManagementUserId(managementUserId);
            String managementNickName = materialVO.getManagementNickName();
            applyStockReturn.setId(null);
            applyStockReturn.setManagementCompanyNo(managementCompanyNo);
            applyStockReturn.setManagementCompanyName(managementCompanyName);
            applyStockReturn.setManagementDeptNo(managementDeptNo);
            applyStockReturn.setManagementDeptName(managementDeptName);
            applyStockReturn.setManagementUserId(managementUserId);
            applyStockReturn.setManagementNickName(managementNickName);
            applyStockReturn.setMaterialName(name);
            applyStockReturn.setMaterialNo(materialNo);
            applyStockReturn.setUseCompanyName(companyName);
            applyStockReturn.setUseCompanyNo(companyNo);
            applyStockReturn.setUseDeptName(useDeptName);
            applyStockReturn.setUseDeptNo(useDeptNo);
            applyStockReturn.setApplyNo(ay.getApplyNo());
            applyStockReturn.setApplyType(ay.getApplyType());
            applyStockReturn.setName(ay.getName());
            applyStockReturn.setApplicantCompanyNo(ay.getApplicantCompanyNo());
            applyStockReturn.setApplicantCompanyName(ay.getApplicantCompanyName());
            applyStockReturn.setApplicantDeptNo(ay.getApplicantDeptNo());
            applyStockReturn.setApplicantDeptName(ay.getApplicantDeptName());
            applyStockReturn.setApplicantUserId(ay.getApplicantUserId());
            applyStockReturn.setApplicantUserNickName(ay.getApplicantUserNickName());
            applyStockReturn.setExt(ay.getExt());
            applyStockReturn.setRemarks(ay.getRemarks());
            applyStockReturn.setCreateAt(date);
            applyStockReturn.setUpdateAt(date);
            applyStockReturn.setUpdateDay(date);
            applyStockReturn.setIsDelete(0);
            for (StockReturnMaterialDTO stockReturnMaterialDTO : stockReturnMaterialDTOS) {
                if (stockReturnMaterialDTO.getMaterialNo().equals(materialNo)){
                    String reginNo = stockReturnMaterialDTO.getReginNo();
                    String reginName = stockReturnMaterialDTO.getReginName();
                    String storageLocation = stockReturnMaterialDTO.getStorageLocation();
                    applyStockReturn.setReginNo(reginNo);
                    applyStockReturn.setReginName(reginName);
                    applyStockReturn.setStorageLocation(storageLocation);
                }
            }
            applyStockReturnMapper.insertSelective(applyStockReturn);
            applyMapper.insertSelective(ay);
        }
         return true;
    }


    private List<MaterialVO> checkMaterialNos(String[] split) {
        String s = CommonStringUtils.toStr(split);
        List<MaterialVO> materialVOS = materialMapper.listMaterialVOByMaterialNos(s);
        if (materialVOS.isEmpty()){
            throw new BizException("找不到对应资产");
        }

        for (int i = 0; i < materialVOS.size(); i++) {
            MaterialVO materialVO = materialVOS.get(i);
            String materialNo = materialVO.getMaterialNo();
            Apply applyByMaterialNo = applyMapper.getApplyByMaterialNo(materialNo);
            if (applyByMaterialNo!=null){
                throw  new BizException("当前"+materialVO.getMaterialNo()+"资产被人申请占用中");
            }
            Integer useStatus = materialVO.getUseStatus();
            if (useStatus==0){
                throw new BizException("编号[" + materialVO.getMaterialNo() + "]是闲置状态,无法退库");
            }
            String[] qualityStatus = materialVO.getQualityStatus();
            if (qualityStatus!=null ||qualityStatus.length>0){
                boolean bl=false;
                for (int j = 0; j < qualityStatus.length; j++) {
                    String qStatus = qualityStatus[j];
                    if (qStatus.equals(QualityStatusEnum.REFUNDABLE.getCode().toString())) {
                        bl = true;
                    }
                }
                if (bl == false) {
                    throw new BizException("编号[" + materialVO.getMaterialNo() + "]资产质量状态设置不可退库");

                }
            }

        }
        return materialVOS;
    }
}